using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using RTMP.SimpleClient.Exceptions;
using RTMP.SimpleClient.Helpers;

namespace RTMP.SimpleClient.MessageReceiver
{
    /// <summary>
    /// 基于网络流的RTMP消息接收器实现
    /// </summary>
    public class NetworkMessageReceiver : IMessageReceiver
    {
        private readonly Stream _networkStream;
        private CancellationTokenSource? _receivingCts;
        private Task? _receivingTask;
        private readonly object _stateLock = new object();
        private bool _disposed = false;

        public event EventHandler<MessageReceivedEventArgs>? MessageReceived;

        public bool IsReceiving { get; private set; }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="networkStream">网络流</param>
        public NetworkMessageReceiver(Stream networkStream)
        {
            _networkStream = networkStream ?? throw new ArgumentNullException(nameof(networkStream));
        }

        /// <summary>
        /// 启动后台消息接收
        /// </summary>
        public async Task StartReceivingAsync(CancellationToken cancellationToken = default)
        {
            ThrowIfDisposed();

            lock (_stateLock)
            {
                if (IsReceiving)
                {
                    throw new RTMPInvalidStateException("消息接收器已经在运行中");
                }

                _receivingCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
                IsReceiving = true;
            }

            try
            {
                // _receivingTask = ReceiveMessagesLoopAsync(_receivingCts.Token);
                await ReceiveMessagesLoopAsync(_receivingCts.Token);
                await Task.CompletedTask;
            }
            catch (Exception)
            {
                lock (_stateLock)
                {
                    IsReceiving = false;
                }
                throw;
            }
        }

        /// <summary>
        /// 停止消息接收
        /// </summary>
        public async Task StopReceivingAsync(CancellationToken cancellationToken = default)
        {
            ThrowIfDisposed();

            lock (_stateLock)
            {
                if (!IsReceiving)
                {
                    return;
                }

                _receivingCts?.Cancel();
                IsReceiving = false;
            }

            if (_receivingTask != null)
            {
                try
                {
                    await _receivingTask.ConfigureAwait(false);
                }
                catch (OperationCanceledException)
                {
                    // 预期的取消异常
                }
                finally
                {
                    _receivingTask = null;
                }
            }
        }

        /// <summary>
        /// 消息接收循环
        /// </summary>
        private async Task ReceiveMessagesLoopAsync(CancellationToken cancellationToken)
        {
            try
            {
                while (!cancellationToken.IsCancellationRequested)
                {
                    try
                    {
                        // 从网络流读取完整的RTMP消息
                        var messageData = await RTMPMessageHelper.ReadMessageAsync(_networkStream, cancellationToken);

                        if (messageData.Length == 0)
                        {
                            // 连接可能已关闭
                            break;
                        }

                        // 解析消息头（需要扩展RTMPMessageHelper来支持从完整消息中提取头信息）
                        var header = ExtractMessageHeader(messageData);
                        var payload = ExtractMessagePayload(messageData, header);

                        // 触发消息接收事件
                        var eventArgs = new MessageReceivedEventArgs(header, payload);
                        MessageReceived?.Invoke(this, eventArgs);
                    }
                    catch (OperationCanceledException)
                    {
                        break;
                    }
                    catch (Exception ex)
                    {
                        // 记录异常但继续接收（可考虑添加重试机制）
                        Console.WriteLine($"消息接收时发生错误: {ex.Message}");

                        // 如果是网络相关的错误，可能需要中断接收循环
                        if (ex is IOException || ex is RTMPException)
                        {
                            break;
                        }
                    }
                }
            }
            finally
            {
                lock (_stateLock)
                {
                    IsReceiving = false;
                }
            }
        }

        /// <summary>
        /// 从完整消息数据中提取消息头信息
        /// 注意：这是一个简化实现，实际应该扩展RTMPMessageHelper
        /// </summary>
        private RTMPMessageHelper.RTMPMessageHeader ExtractMessageHeader(byte[] messageData)
        {
            // 简化实现：假设消息数据就是负载数据
            // 实际实现需要解析RTMP消息头结构
            return new RTMPMessageHelper.RTMPMessageHeader
            {
                Timestamp = 0,
                PayloadLength = (uint)messageData.Length,
                MessageType = RTMPMessageHelper.RTMPMessageType.AMF0Command,
                StreamId = 0
            };
        }

        /// <summary>
        /// 从完整消息数据中提取负载数据
        /// </summary>
        private byte[] ExtractMessagePayload(byte[] messageData, RTMPMessageHelper.RTMPMessageHeader header)
        {
            // 简化实现：返回整个消息数据作为负载
            // 实际实现需要跳过消息头部分
            return messageData;
        }

        public void Dispose()
        {
            if (_disposed) return;

            try
            {
                StopReceivingAsync().GetAwaiter().GetResult();
            }
            catch
            {
                // 忽略关闭时的异常
            }

            _receivingCts?.Dispose();
            _disposed = true;
        }

        private void ThrowIfDisposed()
        {
            if (_disposed)
            {
                throw new ObjectDisposedException(nameof(NetworkMessageReceiver));
            }
        }
    }
}